
###########################################################AUTHORS######################################################################
'''
----------------------------------------------------------------------------------------------------------------------------------------
                                                        ADITHYA AGGARWAL
                                                        DHRUV DHODY
                                                        KRISHNA GOPALAN
                                                        SANDEEP M.R
----------------------------------------------------------------------------------------------------------------------------------------
'''
import os
import string
#import grid
from wxPython.wx import *
from wxPython.ogl import *
from Parser import *
wxOGLInitialize()

_currentlyDraggedUnitOp = ""
_isObjectDraggedFromPalette  = False
_isPortMoving = False
_isConnectionTakingPlace = False
_startPort = wxShape(0)
targetShapeForRightClick = wxShape(0)
_previousuoppos = wxPoint(0,0)
_routingInitSegment = 20
_portshavebeenmoved = false

class FlowSheet:
    def __init__(self,nam):
        self.name = nam
        self.listOfUnitOp = []
        self.listOfFlowSheets = {}
        self.listOfSubFlowSheets = {}
        
class UnitOp(wxDrawnShape):
    PortAttributes = {}
    def __init__(self,parent,_class,nam,flowsh,bool,cliObj,log):

        self._previousuoppos = wxPoint(0,0)

        self.parent=parent
        wxDrawnShape.__init__(self)
        self.textFont = 8
        self.angle = 0
        self._class =_class
        self.CliObj = cliObj
        self.log = log
        global settings,listOfParsedPortFiles,listOfParsedUnitOpFiles
        parsedFile = listOfParsedUnitOpFiles[_class]
        self.name = nam
        self.args = parsedFile.args
        self.flowsh = flowsh
        self.rotate = parsedFile.rotate
            
        if bool:
            self.scale = parsedFile.scale
            pen = wxPen(parsedFile.pen_colour,2,wxSOLID)
            self.listOfPorts = {}
            for type in parsedFile.listOfPorts.keys():
                port_details = parsedFile.listOfPorts[type]
                det = port_details['type_details']                
                self.PortAttributes[type] = {'editable':det['editable'] , 'variable':''}
                list = []
                port_names = []
                cmd = "valueOf " + self.flowsh + self.name + "." + self.getTypeName(type) + ".keys"
                self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
                result = self.CliObj.Eval(cmd)
                temp = result[2:len(result)-2]
                port_names = string.split(temp,"', '")
                i=0
                if port_details.has_key('param'):
                    #assumption that number of fixed ports mentioned in XML file hav 1-1 correspondence with the number returned by CLI
                    for param in port_details['param']:
                        nam = self.flowsh + self.name + "." + port_names[i]
                        port = Port(self,type,param['orient'],param['origin'],param['location'],nam,self.CliObj,self.log )
                        i = i + 1
                        port.SetDraggable(false,false)
                        list.append(port)
                elif result is not "":
                    if det['editable'] == "true":
                        self.PortAttributes[type]['variable'] = det['variable']
                        orient = det['orientation']
                        loc = det['location']
                        if loc == 'top': 
                            y = 0.0
                            x = 1.0/(len(port_names)+1)
                            i = 1.0
                            for name in port_names:
                                nam = self.flowsh + self.name + "." + name
                                origin = (x*i,y)
                                port = Port(self,type,orient,origin,loc,nam,self.CliObj,self.log )
                                list.append(port)
                                i = i + 1.0
                        elif loc == 'bottom':
                            y = 1.0
                            x = 1.0/(len(port_names)+1)
                            i = 1.0
                            for name in port_names:
                                nam = self.flowsh + self.name + "." + name
                                origin = (x*i,y)
                                port = Port(self,type,orient,origin,loc,nam,self.CliObj,self.log )
                                list.append(port)
                                i = i + 1.0                           
                        elif loc == 'left':
                            x = 0.0
                            y = 1.0/(len(port_names)+1)
                            i = 1.0
                            for name in port_names:
                                nam = self.flowsh + self.name + "." + name
                                origin = (x,y*i)
                                port = Port(self,type,orient,origin,loc,nam,self.CliObj,self.log )
                                list.append(port)
                                i = i + 1.0                            
                        elif loc == 'right':
                            x = 1.0
                            y = 1.0/(len(port_names)+1)
                            i = 1.0
                            for name in port_names:
                                nam = self.flowsh + self.name + "." + name
                                origin = (x,y*i)
                                port = Port(self,type,orient,origin,loc,nam,self.CliObj,self.log )
                                list.append(port)
                                i = i + 1.0
                else:
                    self.PortAttributes[type]['variable'] = det['variable']
                self.listOfPorts[type] = list
        else:
            self.scale = 1.0
            pen = wxPen(parsedFile.pen_colour)

        self.size = wxPoint(parsedFile.uopStruct.size.x * self.scale , parsedFile.uopStruct.size.y * self.scale)
        #default size of the unitop in terms of  maximum x and y co-ords
        self.SetSize(self.size.x,self.size.y,true)
        self.SetDrawnPen(pen)
        brush = wxBrush(wxColour(255,255,255),wxTRANSPARENT)
        self.SetDrawnBrush(brush)
        #loop to read in co-ords for straight lines in terms of percentage deviation from the default co-ords read earlier
        if parsedFile.uopStruct.locus.has_key('arc'):
            for arc in parsedFile.uopStruct.locus['arc']:
                x = arc['rect'].x * self.scale
                y = arc['rect'].y * self.scale
                w = arc['rect'].width * self.scale
                h = arc['rect'].height * self.scale
                rect = wxRect(x,y,w,h)
                self.DrawEllipticArc( rect,arc['start'],arc['end'] )
                
        if parsedFile.uopStruct.locus.has_key('straight'):    
            for line in parsedFile.uopStruct.locus['straight']:
                x = line['point1'].x * self.scale
                y = line['point1'].y * self.scale
                point1 = wxPoint(x,y)
                x = line['point2'].x * self.scale
                y = line['point2'].y * self.scale
                point2 = wxPoint(x,y)
                self.DrawLine(point1 , point2)

        #set the characteristics of the drawn object....colour,fill,resizing etc    
        #self.AddText(text)
        self.SetCentreResize(false)
        self.SetShadowMode(SHADOW_NONE)

    def getTypeName(self,nam):
        if nam == 'material_in': return 'ports_mat_IN'
        elif nam == 'material_out': return 'ports_mat_OUT'
        elif nam == 'energy_in': return 'ports_ene_IN'
        elif nam == 'energy_out': return 'ports_ene_OUT'
        
    def GetClass(self):
        return self._class
 
    def GetHeight(self):
        return self.size.y

    def GetWidth(self):
        return self.size.x

    def CalculateBoundaries(self):

        self.top = self.GetY()-self.size.y/2
        self.bottom = self.GetY()+self.size.y/2
        self.left = self.GetX()-self.size.x/2
        self.right = self.GetX()+self.size.x/2
        self.rect = wxRect(self.left,self.top,self.right - self.left,self.bottom - self.top) 
        '''
        global _portshavebeenmoved
        for port_type in self.listOfPorts.values():
            for port in port_type:
                if not _portshavebeenmoved:
                    print "portsmoved"
                    port_top =  port.GetY() - port.size.y/2
                    port_bottom = port.GetY() + port.size.y/2
                    port_left = port.GetX() - port.size.x/2
                    port_right = port.GetX()+ port.size.x/2
                else:
                    print "ports not moved"
                    port_top =  port.previouspos.x - port.size.y/2
                    port_bottom = port.previouspos.y + port.size.y/2
                    port_left = port.previouspos.x - port.size.x/2
                    port_right = port.previouspos.y+ port.size.x/2
                    
                if port_top < self.top:
                    self.top = port_top
                if port_bottom > self.bottom:
                    self.bottom = port_bottom
                if port_left < self.left:
                    self.left = port_left
                if port_right > self.right:
                    self.right = port_right

        self.rect = wxRect(self.left,self.top,self.right - self.left,self.bottom - self.top)          
        for port_type in self.listOfPorts.values():
            for port in port_type:
                port_top =  port.GetY() - port.size.y/2
                port_bottom = port.GetY() + port.size.y/2
                port_left = port.GetX() - port.size.x/2
                port_right = port.GetX()+ port.size.x/2
                if port_top < self.top:
                    self.top = port_top
                if port_bottom > self.bottom:
                    self.bottom = port_bottom
                if port_left < self.left:
                    self.left = port_left
                if port_right > self.right:
                    self.right = port_right
        
        global _routingInitSegment
        self.left = self.left - _routingInitSegment/2
        self.top = self.top - _routingInitSegment/2
        self.right = self.right + _routingInitSegment/2
        self.bottom = self.bottom + _routingInitSegment/2
        '''    
    def GetTop(self):
        return  self.top

    def GetBottom(self):
        return self.bottom

    def GetLeft(self):
        return self.left

    def GetRight(self):
        return self.right

    def GetRect(self):
        return self.rect
    
    def ShowUOP(self,origin):
        self.SetX(origin.x)
        self.SetY(origin.y)
        self._previousuoppos = origin 
        self.Show(true)
        canvas = self.GetCanvas()
        for type in self.listOfPorts.keys():
            for i in range(len(self.listOfPorts[type])):
                port = self.listOfPorts[type][i]
                x = self.listOfPorts[type][i].origin[0]
                y = self.listOfPorts[type][i].origin[1]
                x1 = self.GetX() + (self.size.x * x) - self.size.x/2
                y1 = self.GetY() + (self.size.y * y) - self.size.y/2
                self.listOfPorts[type][i].SetX(x1)
                self.listOfPorts[type][i].SetY(y1)
                port.previouspos = wxPoint(x1,y1)                
                self.listOfPorts[type][i].SetCanvas(canvas)
                self.GetCanvas().GetDiagram().AddShape(self.listOfPorts[type][i])
                self.listOfPorts[type][i].Show(true)
        global _portshavebeenmoved
        _portshavebeenmoved = true
        
    def RelocateUNITOP(self):
        #print "relocate uop"
        self.CalculateBoundaries()
        rect = self.GetRect()
        #self.DrawRectangle(rect)#rect.x,rect.y,rect.width,rect.height)
        #print "SELF.rectANGE",rect
        overlap=False
        for unitop in self.parent.listOfUnitOp:
            unitop.CalculateBoundaries()
            uoprect=unitop.GetRect()
            if uoprect.Intersects(rect) and not unitop==self:    
                overlap=True
                print unitop.name
                break
        if overlap:
            self.SetX(self._previousuoppos.x)
            self.SetY(self._previousuoppos.y)            
        else:
            self._previousuoppos = wxPoint(self.GetX(),self.GetY())
            for type in self.listOfPorts.keys():
                for i in range(len(self.listOfPorts[type])):
                    port = self.listOfPorts[type][i]
                    x = self.listOfPorts[type][i].origin[0]
                    y = self.listOfPorts[type][i].origin[1]
                    x1 = self.GetX() + (self.size.x * x) - self.size.x/2
                    y1 = self.GetY() + (self.size.y * y) - self.size.y/2
                    port.previouspos = wxPoint(x1,y1)                
                
        return overlap
    def RelocateUOP(self):
        for type in self.listOfPorts.values():
            for port in type:
                port.Show(false)
                port.SetX( self.GetX() + (self.size.x * port.origin[0]) - self.size.x/2 )
                port.SetY( self.GetY() + (self.size.y * port.origin[1]) - self.size.y/2 )
                port.Show(true)
        
    def AddLabel(self):
        #set the characteristics for the drawn text
        self.SetDrawnFont(wxFont(self.textFont,wxDEFAULT,wxNORMAL,wxNORMAL))#wxBOLD))
        #self.SetFormatMode(FORMAT_CENTRE_HORIZ )
        self.SetDrawnBackgroundMode(0)#colour appears if mode = 0
        #self.SetDrawnBackgroundColour(wxCYAN)#wxLIGHT_GREY)
        self.SetDrawnTextColour(wxRED)
        #textPosX = -((len(self.name) * (self.textFont - 3)) / 2)
        textPosX = -self.size.x/2
        textPosY =  self.size.y/2 + 4
        textPoint = wxPoint(textPosX, textPosY)
        self.DrawText(self._class,textPoint)
        #pi = 3.1415926535897932384626433832795
        #self.Rotate(0,0,pi * 90.0 )

    def RequestAddPort(self,type):
        variable =self.PortAttributes[type]['variable']
        cmd = self.flowsh + self.name + "." + variable
        self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
        a = self.CliObj.Eval(cmd)
        temp = string.split(a," = ")
        value = int(temp[1]) + 1
        cmd = cmd + " = " + str(value)
        self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
        self.CliObj.Eval(cmd)

    def AddDelPortAccepted(self,type,cmdtype,variable):
        cmd = "valueOf " + self.flowsh + self.name + "." + cmdtype + ".keys"
        CliResult = self.CliObj.Eval(cmd)
        self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
        cli_port_names = []
        List=[]
        temp = CliResult[2:len(CliResult)-2]
        cli_port_names = string.split(temp,"', '")
        cli_len = len(cli_port_names)
        cur_len = len(self.listOfPorts[type])

        port_details = parsedFile.listOfPorts[type]
        det = port_details['type_details']                
        orient = det['orientation']
        loc = det['location']

        
        if cli_len > cur_len: # adding ports
            for name in cli_port_names:
                flag = false
                for port in self.listOfPorts[type]:
                    if self.flowsh + self.name + "." + name == port.name:
                        flag = true
                        break
                if flag == false:
                    List.append(name)

            if loc == 'top': 
                y = 0.0
                x = 1.0/(cli_len+1)
                i = 1.0
                for port in self.listOfPorts[type]:
                    port.origin = (x*i,y)
                    i = i + 1.0
                for name in List:
                    nam = self.flowsh + self.name + "." + name
                    origin = (x*i,y)
                    port = Port(self,type,orient,origin,loc,nam,self.CliObj ,self.log)
                    self.listOfPorts[type].append(port)
                    i = i + 1.0
            elif loc == 'bottom':
                y = 1.0
                x = 1.0/(cli_len+1)
                i = 1.0
                for port in self.listOfPorts[type]:
                    port.origin = (x*i,y)
                    i = i + 1.0
                for name in List:
                    nam = self.flowsh + self.name + "." + name
                    origin = (x*i,y)
                    port = Port(self,type,orient,origin,loc,nam,self.CliObj,self.log )
                    self.listOfPorts[type].append(port)
                    i = i + 1.0                           
            elif loc == 'left':
                x = 0.0
                y = 1.0/(cli_len+1)
                i = 1.0
                for port in self.listOfPorts[type]:
                    port.origin = (x,y*i)
                    i = i + 1.0
                for name in List:
                    nam = self.flowsh + self.name + "." + name
                    origin = (x,y*i)
                    port = Port(self,type,orient,origin,loc,nam,self.CliObj ,self.log)
                    self.listOfPorts[type].append(port)
                    i = i + 1.0                            
            elif loc == 'right':
                x = 1.0
                y = 1.0/(cli_len+1)
                i = 1.0
                for port in self.listOfPorts[type]:
                    port.origin = (x,y*i)
                    i = i + 1.0
                for name in List:
                    nam = self.flowsh + self.name + "." + name
                    origin = (x,y*i)
                    port = Port(self,type,orient,origin,loc,nam,self.CliObj ,self.log)
                    self.listOfPorts[type].append(port)
                    i = i + 1.0
                    

        self.RelocateUOP()                    
    def AddPort(self,type,orient):
        siz = self.GetBoundingBoxMax()
        port = Port( self,type,orient,(  - (10/self.size.x) ,  (10/self.size.x ) ),self.CliObj,self.log )
        can = self.GetCanvas()
        port.SetCanvas(can)
        can.GetDiagram().AddShape(port)
        x = (port.origin[0] * self.size[0]) - self.size[0]/2
        y = (port.origin[1] * self.size[1]) - self.size[1]/2
        port.SetX(self.GetX() + x)
        port.SetY(self.GetY() + y)
        port.Show(true)
        can.Refresh()
        self.listOfPorts[type].append( port )

    def DeletePort(self,type):
        port = self.listOfPorts[type][0]
        port.Show(false)
        self.GetCanvas().GetDiagram().RemoveShape( port )
        self.listOfPorts[type].remove(port)
        self.GetCanvas().Refresh()

    def MovePortRequest(self,port):
        self.GetCanvas().SetCursor(wxCROSS_HAIR)
        global _isPortMoving
        _isPortMoving = true

    def MovePort(self,x,y):
        donothing = 1
        
    def AddPortConnection(self,connectionports):
        self.parent.AddPortConnection(connectionports)
    def GetPort(self,arg):
        for ports in self.listOfPorts.values():
            for port in ports:
                if arg == port.name: return port
    def OnRotate(self,angle):
        location = { 'top-left':0,
                     'top':1,
                     'top-right':2,
                     'right':3,
                     'bottom-right':4,
                     'bottom':5,
                     'bottom-left':6,
                     'left':7 }
        
        orientation = { 'north':0,
                        'south':1,
                        'east':2,
                        'west':3 }
        self.angle = (self.angle + angle) % 360           
        if self.angle == 0:
            factor = 0
            angle_in_radians = 0
            self.size = wxPoint(self.size.x,self.size.y)
        elif self.angle == 90:
            factor = 1
            angle_in_radians = 3.1415926535897932384626433832795 / 2.0
            self.size = wxPoint(self.size.y,self.size.x)
        elif self.angle == 180:
            factor = 2
            angle_in_radians = 3.1415926535897932384626433832795
        elif self.angle == 270:
            factor = 3
            angle_in_radians = 3.1415926535897932384626433832795 * 1.5
            self.size = wxPoint(self.size.y,self.size.x)
            
        for ports in self.listOfPorts.values():
            for port in ports:
                cur_x = port.origin[0] * 100.0
                cur_y = port.origin[1] * 100.0
                if angle == 90:
                    next_x = (100 - cur_y)/100.0
                    next_y = cur_x/100.0
                elif angle == 180:
                    next_x = (100 - cur_x)/100.0
                    next_y = (100 - cur_y)/100.0
                elif angle == 270:
                    next_x = cur_y/100.0
                    next_y = (100 - cur_x)/100.0
                port.origin = (next_x,next_y)
                
                cur_orient = orientation[port.orientation]
                cur_location = location[port.location]
                next_orient = (cur_orient + (1*factor) ) % 4
                next_location = (cur_location + (2*factor) ) % 8
                for loc,val in location.items():
                    if val == next_location:
                        port.location = loc
                        break
                for orient,val in orientation.items():
                    if val == next_orient:
                        port.orientation = orient
                        break
                port.Rotate(0,0,angle_in_radians)
                port.Recompute()
            
        self.Rotate(0,0,angle_in_radians)
        self.Recompute()
        self.SetSize(self.size.x,self.size.y,true)
        self.RelocateUOP()
        can = self.GetCanvas()
        dc = wxClientDC(can)
        can.PrepareDC(dc)
        can.Redraw(dc)
        #for portcon in self.parent.portconnections:
           #portcon.Route(self.parent.listOfUnitOp)
           #portcon.Draw(dc)
        
        can.Refresh()
        
        #Adding the vector layout changes
class Port(wxDrawnShape):
    def __init__(self,parent,type,orient,origin,loc,name,cliObj,log):
        wxDrawnShape.__init__(self)
        parsedFile = listOfParsedPortFiles[type]
        brush = wxBrush(parsedFile.brush)
        brush.SetStyle(wxSOLID)
        self.SetBrush(brush)
        self.SetDrawnPen( wxPen(parsedFile.pen) )
        self.conn_colour = parsedFile.conn_colour
        self.flow = parsedFile.flow
        self.previouspos = wxPoint(0,0)
        self.name = name #  name to be used by sim42PFD nothing to do with me
        self.flow = parsedFile.flow #flow direction in or out
        self.CliObj = cliObj
        self.log = log
        struct = parsedFile.struct[orient]
        self.size = struct.size #default size of the unitop in terms of  maximum x and y co-ords
        self.origin = origin
        
        self.SetSize(self.size.x,self.size.y,true)

        #loop to read in co-ords for straight lines in terms of percentage deviation from the default co-ords read earlier
        if struct.locus.has_key('arc'):
            for arc in struct.locus['arc']:
                self.DrawEllipticArc( arc['rect'],arc['start'],arc['end'] )
                
        if struct.locus.has_key('straight'):
            for line in struct.locus['straight']:
                self.DrawLine(line['point1'],line['point2'])
        
        self.parent = parent
        self.type = type #flag to check whether its an inport or out
        self.orientation = orient
        self.location = loc
        self.CalculateSize()
        self.SetFixedSize(true,true)
        self.connection = None
        self.isconnection = False
        evthand = PortEventHandler(self,self.CliObj,self.log)
        evthand.SetShape(self)
        evthand.SetPreviousHandler(self.GetEventHandler())
        self.SetEventHandler(evthand)

    def ShowPort(self):
        self.Show(false)        
        #self.SetX(x)
        #self.SetY(y)
        self.Show(true)
        self.GetCanvas().Refresh()

    def ShowPortVector(self):
        self.Show(false)        
        #self.SetX(x)
        #self.SetY(y)
        self.Show(true)
        self.GetCanvas().Refresh()
        
    def PortPos(self):
        x = self.GetX()
        y = self.GetY()
        """if self.orientation == 'east':
            x = self.GetX() - self.size.x
            y = self.GetY()
        elif self.orientation == 'west':
            x = self.GetX() - self.size.x
            y = self.GetY()
        elif self.orientation == 'north':            
            x = self.GetX() - self.size.x
            y = self.GetY()
        elif self.orientation == 'south':            
            x = self.GetX() - self.size.x
            y = self.GetY()"""
        return( wxPoint(x,y) )
        
class Palette(wxShapeCanvas):
    def __init__(self, parent,CliObj,log):
        wxShapeCanvas.__init__(self, parent)
        self.CliObj = CliObj
        self.log = log
        self.maxWidth  = 200
        self.maxHeight = 700
        self.SetScrollbars(20, 20, self.maxWidth/20, self.maxHeight/20)
        global settings
        self.SetBackgroundColour(settings['palette_background'])
        #self.SetBackgroundColour(wxCYAN)
        self.buffer = []
        self.diagram =  wxDiagram()
        self.SetDiagram(self.diagram)
        self.diagram.SetCanvas(self)
        self.listOfUnitOp = []
        i = 0
        #brush = wxBrush(wxColor(settings['palette_background']))
        brush = wxBrush(wxColor(0,0,0))
        brush.SetStyle(wxTRANSPARENT)

        for parsedFil in listOfParsedUnitOpFiles.values():
            newuop = UnitOp(self,parsedFil._class,"","",false,self.CliObj,self.log)
            newuop.SetCanvas(self)
            insertflag = 0
            # and insert it in an array sorted on their heights
            if i > 0 : #this condition prevents loop being executed when there is no element in the list
                for j in range(0,i - 1):
                    if self.listOfUnitOp[j].GetHeight() > newuop.GetHeight():
                       self.listOfUnitOp.insert(j,newuop)
                       insertflag = 1
                       break
            else: pass
            
            if insertflag == 0:
                self.listOfUnitOp.append(newuop)
            else: pass
            i = i + 1
      
        curx = 0 # x,y co-ords where the current unitop will be placed
        cury = 10
        maxy = 10
        for j in range(len(self.listOfUnitOp)):
            uop = self.listOfUnitOp[j]
            if(curx + uop.GetWidth() + 10 > self.maxWidth):
                curx = 10
                cury = maxy + 25
            else:
                curx = curx + 10
            self.AddUnitOp( uop, curx + uop.GetWidth()/2, cury + uop.GetHeight()/2 )

            maxy = cury + self.listOfUnitOp[j].GetHeight()
            curx = curx + self.listOfUnitOp[j].GetWidth()

        EVT_WINDOW_DESTROY(self, self.OnDestroy)
        EVT_ENTER_WINDOW(self,self.OnEnter)
   
    def AddUnitOp(self, shape, x, y):
        #shape.SetDrawnBackgroundColour(wxWHITE)#wxLIGHT_GREY)    
        #shape.AddLabel()
        shape.SetX(x)
        shape.SetY(y)
        shape.SetDraggable(false, false)
        shape.SetFixedSize(true,true)
        self.diagram.AddShape(shape)
        shape.Show(true)

        evthandler = PaletteEvtHandler()
        evthandler.SetShape(shape)
        evthandler.SetPreviousHandler(shape.GetEventHandler())
        shape.SetEventHandler(evthandler)

    def OnDestroy(self, evt):
        for shape in self.diagram.GetShapeList():
            if shape.GetParent() == None:
                shape.SetCanvas(None)
                shape.Destroy()
        self.diagram.Destroy()

    def OnEnter(self,evt):
        global _isObjectDraggedFromPalette
        if not _isObjectDraggedFromPalette:
            self.SetCursor(wxSTANDARD_CURSOR)

    def OnLeftClick(self,x,y,key):
        global _currentlyDraggedUnitOp,_isObjectDraggedFromPalette
        _currentlyDraggedUnitOp = None
        _isObjectDraggedFromPalette  = false
        self.SetCursor(wxSTANDARD_CURSOR)#wxSTANDARD_CURSOR

    def OnEndDragLeft(self,x,y,key):
        global _currentlyDraggedUnitOp,_isObjectDraggedFromPalette
        _currentlyDraggedUnitOp = -1
        _isObjectDraggedFromPalette  = false
        self.SetCursor(wxSTANDARD_CURSOR)
    
class WorkArea(wxShapeCanvas):
    sentList =  {}
    UnitOpCounter = {}
    def __init__(self,parent,CliObj,log):
        wxShapeCanvas.__init__(self,parent)#,-1,(0,0),(400,700),wxHSCROLL | wxVSCROLL,"Work Area")
        self.log = log
        self.CliObj = CliObj
        self.maxWidth  = 400
        self.maxHeight = 700
        self.x = 0
        self.y = 0
        self.SetScrollbars(20, 20, self.maxWidth/20, self.maxHeight/20)
        self.SetSize((400,700))
        self.SetBackgroundColour(settings['workarea_background'])
        self.diagram =  wxDiagram()
        self.SetDiagram(self.diagram)
        self.diagram.SetCanvas(self)
        self.MainFlowSheet = FlowSheet('/')
        self.listOfUnitOp = []
        self.numberOfUnitOps = 0
        self.currentlyDraggedUnitOp = -1
        self.isObjectDraggedFromPalette = false
        self.beginingOfOutline = wxPoint(0,0)
        self.previousPointInDrag = wxPoint(0,0)
        self.unitopmenu = wxMenu()
        self.MakeUnitopMenu()
        self.portmenu = self.MakePortMenu()
        
        self.portconnections=[]
        
        #EVT_LEFT_UP(self, self.OnLeftUp)
        global listOfParsedUnitOpFiles
        for fil in listOfParsedUnitOpFiles.values():
            self.UnitOpCounter[fil._class] = 1
        EVT_WINDOW_DESTROY(self, self.OnDestroy)
        EVT_ENTER_WINDOW(self,self.OnEnter)
        EVT_CHAR(self, self.OnKeyPress)
    def getWidth(self):
        return self.maxWidth
    
    def getHeight(self):
        return self.maxHeight
    def OnDestroy(self, evt):
        for shape in self.diagram.GetShapeList():
            if shape.GetParent() == None:
                shape.SetCanvas(None)
                shape.Destroy()
        self.diagram.Destroy()
   
    def OnLeftClick(self,x,y,key):
        shapelist = self.GetDiagram().GetShapeList()
        toUnselect = []
        dc = wxClientDC(self)
        self.PrepareDC(dc)
        brush = wxBrush(wxCYAN)
        brush.SetStyle(wxTRANSPARENT)
        for s in shapelist:
            if s.Selected():
                toUnselect.append(s)

        if toUnselect:
            for s in toUnselect:
                s.Select(false, dc)
                self.Redraw(dc)
            self.Refresh()
   
        global _isObjectDraggedFromPalette,_currentlyDraggedUnitOp,listOfParsedUnitOpFiles
        if (_isObjectDraggedFromPalette ):
            nam = listOfParsedUnitOpFiles[_currentlyDraggedUnitOp].name
            incr = repr( self.UnitOpCounter[_currentlyDraggedUnitOp] )
            self.sentList[nam + incr] = { '_class':_currentlyDraggedUnitOp , 'x':x , 'y':y }
            if listOfParsedUnitOpFiles[_currentlyDraggedUnitOp].args == "":
                cmd = '/' + nam + incr + ' = ' + _currentlyDraggedUnitOp + '()'
            else:                
                cmd = '/' + nam + incr + ' = ' + _currentlyDraggedUnitOp + '("' + listOfParsedUnitOpFiles[_currentlyDraggedUnitOp].args + '")'
            self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
            self.CliObj.Eval(cmd)
  
    def AddUnitOp(self,uniop,x, y):
        origin = wxPoint( x ,y )
        uniop.SetDrawnBackgroundColour(wxCYAN)
        uniop.ShowUOP(origin)
        self.UnitOpCounter[uniop._class] = self.UnitOpCounter[uniop._class] + 1
        uniop.SetDraggable(true, true)
        self.diagram.AddShape(uniop)
        uniop.Show(true)
        #self.Refresh()

        evthandler = WorkAreaEvtHandler()
        evthandler.SetShape(uniop)
        evthandler.SetPreviousHandler(uniop.GetEventHandler())
        uniop.SetEventHandler(evthandler)

        dc = wxClientDC(self)
        self.PrepareDC(dc)
        for portcon in self.portconnections:
           portcon.Route(self.listOfUnitOp)
           portcon.Draw(dc)
        self.Refresh()
        
    def drawImage(self,bmp):
        dc = wxPaintDC(self)
        dc.DrawBitmap(bmp, 0, 0, 0)

    def OnBeginDragLeft(self,x,y,key):
        self.beginingOfOutline.x = x
        self.beginingOfOutline.y = y

    def OnDragLeft(self,draw,x,y,key):
        dc = wxClientDC(self)
        self.PrepareDC(dc)
        if (x > self.previousPointInDrag.x):
            clipx = self.previousPointInDrag.x
        else:
            clipx = x
        if(y > self.previousPointInDrag.y):
            clipy = self.previousPointInDrag.y
        else:
            clipy = y
        self.GetDiagram().DrawOutline(dc,self.beginingOfOutline.x,self.beginingOfOutline.y,x,y)            
        #self.DrawOutline(dc,x,y)
        #dc.SetClippingRegion(self.beginingOfOutline.x + 1,self.beginingOfOutline.y + 1,clipx,clipy)
        
        if draw:
            self.Refresh()
        self.previousPointInDrag.x = x
        self.previousPointInDrag.y = y
        #dc.DestroyClippingRegion()

    def OnEndDragLeft(self,x,y,key):
        self.beginingOfOutline.x = 0
        self.beginingOfOutline.y = 0
        self.previousPointInDrag.x = 0
        self.previousPointInDrag.y = 0
        #self.Refresh()

    def OnEnter(self,evt):
        global _isObjectDraggedFromPalette
        if _isObjectDraggedFromPalette:
            self.SetCursor(wxCROSS_CURSOR)

    def OnKeyPress(self, event):
        if event.GetKeyCode() == 127:
            shapelist = self.GetDiagram().GetShapeList()
            toDelete = []
            dc = wxClientDC(self)
            self.PrepareDC(dc)
            for s in shapelist:
                if s.Selected():
                    toDelete.append(s)

            if toDelete:
                for s in toDelete:
                    cmd = "delete " + "'"+  s.flowsh + s.name +"'"
                    self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
                    self.CliObj.Eval(cmd)

    def DrawOutline(self,dc,x,y):
        dc.SetPen(wxPen(wxCYAN))
        dc.DrawRectangle(self.beginingOfOutline.x,self.beginingOfOutline.y,self.previousPointInDrag.x,self.previousPointInDrag.y)
        dc.SetPen(wxPen(wxBLACK,1,wxDOT))
        dc.DrawRectangle(self.beginingOfOutline.x,self.beginingOfOutline.y,x - self.beginingOfOutline.x,y - self.beginingOfOutline.y)
    
    def MakeUnitopMenu(self):
        self.addmenu = wxMenu()
        a = self.GetID("material_in","add")
        b = self.GetID("material_out","add")
        c = self.GetID("energy_in","add")
        d = self.GetID("energy_out","add")
        self.addmenu.Append(a, "material_in", kind = wxITEM_NORMAL)
        self.addmenu.Append(b, "material_out", kind = wxITEM_NORMAL)
        self.addmenu.Append(c, "energy_in", kind = wxITEM_NORMAL)
        self.addmenu.Append(d, "energy_out", kind = wxITEM_NORMAL)
        EVT_MENU(self,a, self.OnAddMaterialInPort)
        EVT_MENU(self,b, self.OnAddMaterialOutPort)
        EVT_MENU(self,c, self.OnAddEnergyInPort)
        EVT_MENU(self,d, self.OnAddEnergyOutPort)
        a = self.GetID("material_in","delete")
        b = self.GetID("material_out","delete")
        c = self.GetID("energy_in","delete")
        d = self.GetID("energy_out","delete")
        self.delmenu = wxMenu()
        self.delmenu.Append(a, "material_in", kind = wxITEM_NORMAL)
        self.delmenu.Append(b, "material_out", kind = wxITEM_NORMAL)
        self.delmenu.Append(c, "energy_in", kind = wxITEM_NORMAL)
        self.delmenu.Append(d, "energy_out", kind = wxITEM_NORMAL)
        EVT_MENU(self, a, self.OnDeleteMaterialInPort)
        EVT_MENU(self, b, self.OnDeleteMaterialOutPort)
        EVT_MENU(self, c, self.OnDeleteEnergyInPort)
        EVT_MENU(self, d, self.OnDeleteEnergyOutPort)

        self.rotatemenu = wxMenu()
        self.rotatemenu.Append(20, "-> 90", kind = wxITEM_NORMAL)
        self.rotatemenu.Append(21, "-> 180", kind = wxITEM_NORMAL)
        self.rotatemenu.Append(22, "-> 270", kind = wxITEM_NORMAL)
        EVT_MENU(self, 20, self.OnRotate90)
        EVT_MENU(self, 21, self.OnRotate180)
        EVT_MENU(self, 22, self.OnRotate270)
        

        self.unitopmenu.AppendMenu(11,'Add Port',self.addmenu)
        self.unitopmenu.AppendMenu(12,'Delete Port',self.delmenu)
        self.unitopmenu.AppendMenu(13,'Virtually Rotate',self.rotatemenu)

    def OnRotate90(self,evt):
        global targetShapeForRightClick
        targetShapeForRightClick.OnRotate(90)

    def OnRotate180(self,evt):
        global targetShapeForRightClick
        targetShapeForRightClick.OnRotate(180)
        
    def OnRotate270(self,evt):
        global targetShapeForRightClick
        targetShapeForRightClick.OnRotate(270)

    def GetID(self,portType,op):
        if portType == "material_in":
            id = 103
        elif portType == "material_out":
            id = 104
        elif portType == "energy_in":
            id = 105
        elif portType == "energy_out":
            id = 106
        if op == "delete":
            id = id + 4
        return id
            
    def MakePortMenu(self):
        menu = wxMenu()
        menu.Append(2, "Properties", kind = wxITEM_NORMAL)
        menu.Append(3, "Move", kind = wxITEM_NORMAL)
        EVT_MENU(self, 2, self.PropertiesOfPort)
        EVT_MENU(self, 3, self.MovePort)
        return menu

    def OnAddMaterialInPort(self,evt):
        global targetShapeForRightClick
        #print evt.GetInt()
        print evt.GetString()
        targetShapeForRightClick.RequestAddPort('material_in')
        
    def OnAddMaterialOutPort(self,evt):
        
        global targetShapeForRightClick
        targetShapeForRightClick.RequestAddPort('material_out')

    def OnAddEnergyInPort(self,evt):
        
        global targetShapeForRightClick
        targetShapeForRightClick.RequestAddPort('energy_in')

    def OnAddEnergyOutPort(self,evt):
        
        global targetShapeForRightClick
        targetShapeForRightClick.RequestAddPort('energy_out')
   
    def OnDeleteMaterialInPort(self,evt):
        global targetShapeForRightClick
        targetShapeForRightClick.DeletePort('material_in')

    def OnDeleteMaterialOutPort(self,evt):
        global targetShapeForRightClick
        targetShapeForRightClick.DeletePort('material_out')

    def OnDeleteEnergyInPort(self,evt):
        global targetShapeForRightClick
        targetShapeForRightClick.DeletePort('energy_in')

    def OnDeleteEnergyOutPort(self,evt):
        global targetShapeForRightClick
        targetShapeForRightClick.DeletePort('energy_out')

    def PropertiesOfPort(self,evt):
        donothing = 1

    def MovePort(self,evt):
        global targetShapeForRightClick
        #targetShapeForRightClick.parent.MovePortRequest(targetShapeForRightClick)

    def RightClickForUnitop(self,pt,shape):
        global targetShapeForRightClick
        targetShapeForRightClick = shape
        for type,attr in shape.PortAttributes.items():
            id = self.GetID(type,"add")
            if attr['editable'] == "false":
                self.addmenu.Enable(id,false)
            else:
                self.addmenu.Enable(id,true)
        if shape.rotate:
            self.rotatemenu.Enable(20,true)
            self.rotatemenu.Enable(21,true)
            self.rotatemenu.Enable(22,true)
        else:
            self.rotatemenu.Enable(20,false)
            self.rotatemenu.Enable(21,false)
            self.rotatemenu.Enable(22,false)
            
        self.PopupMenu(self.unitopmenu, pt)
    
    def RightClickForPort(self,pt,shape):
        global targetShapeForRightClick
        targetShapeForRightClick = shape
        #self.PopupMenu(self.portmenu, pt)

    def Message(self,message,args):
        global _currentlyDraggedUnitOp,_isObjectDraggedFromPalette
        #self.log.WriteText('Sim42PFD.PyInfoMessage: ' + str(message) + ',' +  str(args) + "\n")
        if message == 'CMDNotifyCreateObj':
            if self.sentList.has_key(args[1]):
                newuop = UnitOp( self,self.sentList[args[1]]['_class'] , args[1] , args[0] , true,self.CliObj,self.log)
                newuop.SetCanvas(self)
                #self.listOfUnitOp[args[1]]['_class']].append(newop)
                self.listOfUnitOp.append(newuop)
                x = self.sentList[args[1]]['x']
                y = self.sentList[args[1]]['y']
                self.AddUnitOp(self.listOfUnitOp[self.numberOfUnitOps],x,y)
                self.SetCursor(wxSTANDARD_CURSOR)
                dc = wxClientDC(self)
                self.PrepareDC(dc)
                self.listOfUnitOp[self.numberOfUnitOps].Select(true,dc)
                self.numberOfUnitOps = self.numberOfUnitOps + 1
                self.SetCursor(wxSTANDARD_CURSOR)
                del self.sentList[ args[1] ]
                _currentlyDraggedUnitOp = ""
                _isObjectDraggedFromPalette = false
                self.Refresh(True)
        elif message == 'CMDNotifyDeleteObj':
            for s in self.listOfUnitOp:
                if s.flowsh + s.name == args[1]:
                    self.DeleteUOP(s)
        elif message == 'CMDNotifyConnect':
            connectionports = []
            _startPort = self.GetUOPByName(args[0]).GetPort(args[0])
            _endPort = self.GetUOPByName(args[1]).GetPort(args[1])
            connectionports.append(_startPort)
            connectionports.append(_endPort)
            self.AddPortConnection(connectionports)
        elif message == 'CMDNotifySetValue':
            #print "CMDNotifySetValue"
            temp = string.split(args[0],".")
            variable = temp[len(temp)-1]
            #print variable
            uop = self.GetUOPByName(args[0])
            #print uop
            type = self.GetTypeByVariable(uop,variable)
            #print type
            cmdtype = uop.getTypeName(type)
            uop.AddDelPortAccepted(type,cmdtype,variable)
            
    def GetTypeByVariable(self,uop,variable):
        for type,port_details in uop.PortAttributes.items():
            if port_details['editable'] == "true":
                if port_details['variable'] == variable:
                    return type
                
            
        
    def GetUOPByName(self,arg):
        temp = string.split(arg,'.')
        nam = temp[0]
        for i in range(1,len(temp)-1,1):
            nam = nam + '.' + temp[i]
         
        for uop in self.listOfUnitOp:
            if nam == uop.flowsh + uop.name:
                return uop
           
    def DeleteUOP(self,s):
        dc = wxClientDC(self)
        self.PrepareDC(dc)
        dig = self.GetDiagram()
        self.listOfUnitOp.remove(s)
        s.Select(false,dc)
        s.Show(false)
        self.numberOfUnitOps = self.numberOfUnitOps - 1
                
        for type,ports in s.listOfPorts.items():
            for i in range(len(ports)):
                p = ports.pop()
                #print "on delete - is connection", p.name,p.connection,p.isconnection
                if p.isconnection:
                    self.portconnections.remove(p.connection)
                    p.connection.OnDelete()
                p.Show(false)
                dig.RemoveShape(p)
            del s.listOfPorts[type]
        dig.RemoveShape(s)
        self.Redraw(dc)
        self.Refresh()
        
    def AddPortConnection(self,connectionports):
        dc = wxClientDC(self)
        self.PrepareDC(dc)
        self.FromPort=connectionports[0]
        self.ToPort=connectionports[1]
        conn = PortConnection(self,self.FromPort,self.ToPort)
        self.portconnections.append(conn)
        self.ToPort.connection=conn
        self.ToPort.isconnection = True
        self.FromPort.connection=conn
        self.FromPort.isconnection = True
        
        #print "add", self.FromPort.name,self.ToPort.name,self.FromPort.connection,self.ToPort.connection
        for portcon in self.portconnections:
           portcon.Route(self.listOfUnitOp)
           portcon.Draw(dc)
        self.Refresh()
        
class PortConnection:
    def __init__(self,parent,ConnectPortFrom,ConnectPortTo):
        #see to it that the connectportfrom is always to the left of the connectportto
        self.parent=parent
        self.fromisonleft=true 
        if ConnectPortFrom.PortPos()[0]>ConnectPortTo.PortPos()[0]:
            self.ConnectUnitOpFrom=ConnectPortTo.parent
            self.ConnectPortFrom=ConnectPortTo
            self.ConnectUnitOpTo=ConnectPortFrom.parent
            self.ConnectPortTo=ConnectPortFrom
            #print "greater"
            self._UnitOpsHaveBeenSwapped=true
            self.fromisonleft=false 
        else:    
            self.ConnectUnitOpFrom = ConnectPortFrom.parent
            self.ConnectUnitOpTo = ConnectPortTo.parent
            self.ConnectPortFrom = ConnectPortFrom
            self.ConnectPortTo = ConnectPortTo
            #print "lesser"
            self._UnitOpsHaveBeenSwapped=false      
        self.x1 = self.ConnectPortFrom.PortPos()[0]
        self.y1 = self.ConnectPortFrom.PortPos()[1]
        self.x2 = self.ConnectPortTo.PortPos()[0]
        self.y2 = self.ConnectPortTo.PortPos()[1]
        
        self.recursioncount = 0 
        x1,x2,y1,y2 = self.x1,self.x2,self.y1,self.y2
        self.PortConnectionSegment = []
        self.uoplist=[]
        self.contextuops = []   
        self.PortSegment = 20  
        self.contextrect = None
        self.contextuopCount = 0
        
        self.foundrow=False
        self.foundcol=False

        self.xend=self.x2
        self.yend=max(y1,y2)

        self.FromPortInitSegment = None
        self.ToPortInitSegment = None
        self._UnitOpsHaveBeenSwapped=false
        
    def CheckRoute(self):
        
        #check if routing is necessary
        #print "check called"
        success=True
        if self.PortConnectionSegment==[]:
            success=False
        foundrow,foundcol=False,False
        for i in range(1,len(self.PortConnectionSegment)):
            segment = self.PortConnectionSegment[i]
        #for segment in self.PortConnectionSegment:
            if segment.CheckIfHSegment():
                foundrow=self.FindUopInRow(segment.SegmentFromPos,segment.SegmentToPos)
            else:
                foundcol=self.FindUopInColumn(segment.SegmentFromPos,segment.SegmentToPos)
            if segment==self.PortConnectionSegment[0] or segment==self.PortConnectionSegment[len(self.PortConnectionSegment)-1]:
                continue
            if foundrow or foundcol:
               success=False
               #print "found uop"
               break
            #print "na"
        return success    


    def Route(self,uoplist):
        repaint=False
        
        #the "from" port should always be to the left of the "to" port
        if self.ConnectPortFrom.PortPos()[0]>self.ConnectPortTo.PortPos()[0]:
            self.ConnectUnitOpFrom,self.ConnectUnitOpTo,self.ConnectPortFrom,self.ConnectPortTo=self.ConnectPortTo.parent,self.ConnectPortFrom.parent,self.ConnectPortTo,self.ConnectPortFrom
            self._UnitOpsHaveBeenSwapped=True 
        success= false
        #if self.ConnectPortFrom.PortPos()==wxPoint(self.x1,self.y1) and self.ConnectPortTo.PortPos()==wxPoint(self.x2,self.y2):
        #    success = self.CheckRoute()
        if self.x1==self.ConnectPortFrom.PortPos()[0] and self.y1==self.ConnectPortFrom.PortPos()[1] and self.x2==self.ConnectPortTo.PortPos()[0] and self.y2==self.ConnectPortTo.PortPos()[1]:
            success=self.CheckRoute()
        if success:
            #print "no need"
            return

        self.x1 = self.ConnectPortFrom.PortPos()[0]
        self.y1 = self.ConnectPortFrom.PortPos()[1]
        self.x2 = self.ConnectPortTo.PortPos()[0]
        self.y2 = self.ConnectPortTo.PortPos()[1]
        
        x1 = self.ConnectPortFrom.PortPos()[0]
        y1 = self.ConnectPortFrom.PortPos()[1]
        x2 = self.ConnectPortTo.PortPos()[0]
        y2 = self.ConnectPortTo.PortPos()[1]
        self.x1,self.x2,self.y1,self.y2=x1,x2,y1,y2
        
        for j in range(len(self.PortConnectionSegment)):
            segment = self.PortConnectionSegment.pop()
            segment.line.Show(false)
            self.parent.GetDiagram().RemoveShape(segment.line)
        self.PortConnectionSegment=[]
        
        self.start=wxPoint(x1,y1)
        self.end=wxPoint(x2,y2)
        self.oldstart=self.start
        self.oldend=self.end
        
        self.FindInitSegment()
        self.GetContextRect()        

        self.xend=x1
        self.yend=max(y1,y2)

        Segments=self.RouteTwoSegment(self.start,self.end)
        if not Segments==[]:
            self.PortConnectionSegment.append(self.PortFromInitSegment)
            for segment in Segments:
                self.PortConnectionSegment.append(segment)
                success=True
            self.PortConnectionSegment.append(self.PortToInitSegment)    

        if not success:
            Segments = self.RouteThreeSegment(self.start,self.end)
            if not Segments==[]:
                #print "3 success"
                self.PortConnectionSegment.append(self.PortFromInitSegment)
                for segment in Segments:
                    #print "count"
                    self.PortConnectionSegment.append(segment)
                    success=True
                self.PortConnectionSegment.append(self.PortToInitSegment)

        if not success:
            Segments = self.ThreeSegmentExpanded()
            if not Segments==[]:
                #print "3 success"
                self.PortConnectionSegment.append(self.PortFromInitSegment)
                for segment in Segments:
                    #print "count"
                    self.PortConnectionSegment.append(segment)
                    success=True
                self.PortConnectionSegment.append(self.PortToInitSegment)
                
        if not success:
            Segments = self.RouteFourSegment(self.start,self.end)
            if not Segments==[]:
                #print "3 success"
                self.PortConnectionSegment.append(self.PortFromInitSegment)
                for segment in Segments:
                    #print "count"
                    self.PortConnectionSegment.append(segment)
                    success=True
                self.PortConnectionSegment.append(self.PortToInitSegment)               
        if not success:
            Segments = self.RouteFiveSegment(self.start,self.end)
            if not Segments==[]:
                #print "3 success"
                self.PortConnectionSegment.append(self.PortFromInitSegment)
                for segment in Segments:
                    #print "count"
                    self.PortConnectionSegment.append(segment)
                    success=True
                self.PortConnectionSegment.append(self.PortToInitSegment)               

    def RouteTwoSegment(self,source,destination):
        
        success = False
        x1 = source.x
        y1 = source.y
        x2 = destination.x
        y2 = destination.y
        self.foundrow,self.foundcol = False,False
        segments=[]
        if source.x==destination.x or source.y==destination.y:
            return segments
        
        self.foundcol = self.FindUopInColumn(wxPoint(x2,y1),wxPoint(x2,y2))
        self.foundrow = self.FindUopInRow(wxPoint(x1,y1),wxPoint(x2,y1))
        #print foundrow,foundcol
        if (not self.foundrow) and (not self.foundcol):
            segments.append(PortConnectionSegment(self.parent,self,wxPoint(x1,y1),wxPoint(x2,y1)))
            segments.append(PortConnectionSegment(self.parent,self,wxPoint(x2,y1),wxPoint(x2,y2)))
        else:
            self.foundrow = self.FindUopInRow(wxPoint(x1,y2),wxPoint(x2,y2))
            self.foundcol = self.FindUopInColumn(wxPoint(x1,y1),wxPoint(x1,y2))
            if (not self.foundcol) and (not self.foundrow):
                segments.append(PortConnectionSegment(self.parent,self,wxPoint(x1,y1),wxPoint(x1,y2)))
                segments.append(PortConnectionSegment(self.parent,self,wxPoint(x1,y2),wxPoint(x2,y2))) 
                success = True
                pass
        return segments
    
    def RouteThreeSegment(self,source,destination):
        #case = self.FindThreeSegmentCase()
        #self.case=case
        x1 = source.x
        y1 = source.y
        x2 = destination.x
        y2 = destination.y
        segments=[]
        xhopcounter=10
        yhopcounter=10
        NoSoln = True
        
        xcontrol=self.end.x
        ystart= min(self.start.y,self.end.y)

        self.yend=max(self.start.y,self.end.y)
        y=ystart
        case=1
        segments = []
        if case==1 or case==2:
            #y = y1
            x =x1
            found1,found2,found3 = False,False,False
            self.foundrow,self.foundcol=False,False
            self.portConnectionSegment=[]
            
            while NoSoln and x<=xcontrol and not self.foundrow==True:
                x=x+xhopcounter
                self.foundrow = self.FindUopInRow(wxPoint(x1,y1),wxPoint(x,y1))
                found2 = self.FindUopInColumn(wxPoint(x,y1),wxPoint(x,y2))
                found3 = self.FindUopInRow(wxPoint(x,y2),wxPoint(x2,y2))
                #print found1,found2,found3
                if (not self.foundrow and not found2 and not found3):
                    segments.append(PortConnectionSegment(self.parent,self,wxPoint(x1,y1),wxPoint(x,y1)))
                    segments.append(PortConnectionSegment(self.parent,self,wxPoint(x,y1),wxPoint(x,y2)))
                    segments.append(PortConnectionSegment(self.parent,self,wxPoint(x,y2),wxPoint(x2,y2)))
                    NoSoln = False
            if self.foundrow:
                self.xend=x
                
            found1,found2,found3 = False,False,False         
            while (NoSoln and y<=self.yend and not self.foundcol==True):
                y=y+yhopcounter
                self.foundcol = self.FindUopInColumn(wxPoint(x1,y1),wxPoint(x1,y))
                found2 = self.FindUopInRow(wxPoint(x1,y),wxPoint(x2,y))
                found3 = self.FindUopInColumn(wxPoint(x2,y),wxPoint(x2,y2))
                #print found1,found2,found3  
                if (not self.foundcol and not found2 and not found3):
                    segments.append(PortConnectionSegment(self.parent,self,wxPoint(x1,y1),wxPoint(x1,y)))
                    segments.append(PortConnectionSegment(self.parent,self,wxPoint(x1,y),wxPoint(x2,y)))
                    segments.append(PortConnectionSegment(self.parent,self,wxPoint(x2,y),wxPoint(x2,y2)))
                    NoSoln = False
            if self.foundcol:
                self.yend=y         
        return segments

    def ThreeSegmentExpanded(self):
        foundup=False
        founddown=False
        segments=[]
        #contextlimit=self.contextrect.GetHeight()*10
        loopcount=0
        looplimit=20
        #print found
        while(loopcount<looplimit):
            #print "hi"
            loopcount=loopcount+1
            self.ExpandContextRectUp()
            top=min(self.contextrect.GetTop(),self.contextrect.GetBottom())
            foundup=self.FindUopInColumn(self.start,wxPoint(self.start.x,top))
            if not foundup:
                segments=self.RouteTwoSegment(wxPoint(self.start.x,top),self.end)
                if not segments==[]:
                    #print "in"
                    segments1=[]
                    segments1.append(PortConnectionSegment(self.parent,self,self.start,wxPoint(self.start.x,top)))
                    for segment in segments:
                        segments1.append(segment)
                    return segments1

            self.ExpandContextRectDown()
            bottom=max(self.contextrect.GetTop(),self.contextrect.GetBottom())
            founddown=self.FindUopInColumn(self.start,wxPoint(self.start.x,bottom))
            if not founddown:
                segments=self.RouteTwoSegment(wxPoint(self.start.x,bottom),self.end)
                if not segments==[]:
                    segments1=[]
                    segments1.append(PortConnectionSegment(self.parent,self,self.start,wxPoint(self.start.x,bottom)))
                    for segment in segments:
                        segments1.append(segment)
                    return segments1
        
        return segments


    def RouteFourSegment(self,source,destination):
        segments=[]
        xstart=source.x
        ystart=source.y
        xend=destination.x
        yend=destination.y
        foundrow,foundcol=False,False
        self.foundrow,self.foundcol=False,False
        xhop=10
        yhop=10
        #ystart,yend= min(ystart,yend),max(ystart,yend)
        x=xstart
        y=ystart
        NoSoln=True
        
        while(NoSoln and x<xend and foundrow==False):
            #print NoSoln,foundrow
            x=x+xhop
            foundrow = self.FindUopInRow(wxPoint(xstart,ystart),wxPoint(x,ystart))
            if not foundrow:
                #print "in"
                segments = self.RouteThreeSegment(wxPoint(x,ystart),destination)
                if not segments==[]:
                    #print "soln"
                    segments1=[]
                    segments1.append(PortConnectionSegment(self.parent,self,wxPoint(xstart,ystart),wxPoint(x,ystart)))
                    for segment in segments:
                        segments1.append(segment)
                    segments=segments1    
                    NoSoln=False
            #print NoSoln,foundrow,self.foundrow
                #if self.foundrow==True:
                #    break
                    
        while(NoSoln and y<yend and foundcol==False):
            #print NoSoln,foundrow
            y=y+yhop
            foundcol = self.FindUopInColumn(wxPoint(xstart,ystart),wxPoint(xstart,y))
            if not foundcol:
                #print "in"
                segments = self.RouteThreeSegment(wxPoint(xstart,y),destination)
                if not segments==[]:
                    #print "soln found"
                    segments1=[]
                    segments1.append(PortConnectionSegment(self.parent,self,wxPoint(xstart,ystart),wxPoint(xstart,y)))
                    for segment in segments:
                        segments1.append(segment)
                    segments=segments1    
                    NoSoln=False
                #if self.foundrow==True:
                #    break
        return segments
        

    def RouteFiveSegment(self,source,destination):
        segments=[]
        #return segments
        xstart=source.x
        ystart=source.y
        xend=destination.x
        yend=destination.y
        foundrow,foundcol=False,False
        xhop=10
        yhop=10
        if ystart>yend:
            flag=True
        #ystart,yend= min(ystart,yend),max(ystart,yend)
        x=xstart
        y=ystart
        NoSoln=True
        while(NoSoln and x<xend and foundrow==False):
            x=x+xhop
            foundrow = self.FindUopInRow(wxPoint(xstart,ystart),wxPoint(x,ystart))
            if not foundrow:
                #print "in"
                segments = self.RouteFourSegment(wxPoint(x,ystart),destination)
                if not segments==[]:
                    #print "soln found"
                    segments1=[]
                    segments1.append(PortConnectionSegment(self.parent,self,wxPoint(xstart,ystart),wxPoint(x,ystart)))
                    for segment in segments:
                        segments1.append(segment)
                    segments=segments1    
                    NoSoln=False
        #print y,yend            
        while(NoSoln and y<yend and foundcol==False):
            #print NoSoln,foundrow
            #print "in 5y"
            y=y+yhop
            foundcol = self.FindUopInColumn(wxPoint(xstart,ystart),wxPoint(xstart,y))
            #print xstart,xend,ystart,yend,y
            #print foundcol,y,yend           
            if not foundcol:
                #print "in"
                segments = self.RouteFourSegment(wxPoint(xstart,y),destination)
                if not segments==[]:
                    #print "soln found"
                    segments1=[]
                    segments1.append(PortConnectionSegment(self.parent,self,wxPoint(xstart,ystart),wxPoint(xstart,y)))
                    for segment in segments:
                        segments1.append(segment)
                    segments=segments1    
                    NoSoln=False
        y=ystart            
        while(NoSoln and y>yend and foundcol==False):
            pass
            #print NoSoln,foundrow
            #print "in 5y"
            y=y-yhop
            foundcol = self.FindUopInColumn(wxPoint(xstart,ystart),wxPoint(xstart,y))
            #print xstart,xend,ystart,yend,y
            #print foundcol,y,yend           
            if not foundcol:
                #print "in"
                segments = self.RouteFourSegment(wxPoint(xstart,y),destination)
                if not segments==[]:
                    #print "soln found"
                    segments1=[]
                    segments1.append(PortConnectionSegment(self.parent,self,wxPoint(xstart,ystart),wxPoint(xstart,y)))
                    for segment in segments:
                        segments1.append(segment)
                    segments=segments1    
                    NoSoln=False            
        return segments


    def Draw(self,dc):
        
         self.recursioncount=0
         if not self.PortConnectionSegment==[]:
             for segment in self.PortConnectionSegment:
                segment.Draw(dc)
             
    def FindUopInRow(self,source,destination):

        #find the uop that intersects the line        
        for uop in self.parent.listOfUnitOp :
            uop.CalculateBoundaries()
            left = uop.GetLeft()#uop.pos.x-uop.portBmp.GetWidth()-6
            right= uop.GetRight()#left+uop.bmp.GetWidth()+2*uop.portBmp.GetWidth()+12
           
            top = uop.GetTop()#uop.pos.y
            bottom = uop.GetBottom()#uop.pos.y+uop.bmp.GetHeight()
            if source.y>=top and source.y<=bottom:# and source.x>uop.pos.x+uop.bmp.GetWidth()+uop.portBmp.GetWidth()+6) :
                if source.x<destination.x:
                    if source.x < right and destination.x > left:
                        #print "found in row"
                        return True
                    elif source.x > left and destination.x < right:
                        #print "found in row"
                        return True
        return False
        
    def FindUopInColumn(self,source,destination):

        #find the uop that intersects the line         
        for uop in self.parent.listOfUnitOp:
            uop.CalculateBoundaries()
            left = uop.GetLeft()#uop.pos.x-uop.portBmp.GetWidth()-6
            right= uop.GetRight()#left+uop.bmp.GetWidth()+2*uop.portBmp.GetWidth()+12
            top = uop.GetTop()#uop.pos.y
            bottom = uop.GetBottom()#uop.pos.y+uop.bmp.GetHeight()
            
            if source.x<=right and source.x>=left:# and source.x>uop.pos.x+uop.bmp.GetWidth()+uop.portBmp.GetWidth()+6) :
                if source.y<destination.y:
                    if source.y < bottom and destination.y > top:
                        #print "found in row"
                        return True
                elif source.y > top and destination.y < bottom:
                       #print "found in row"
                    return True
        return False
    

    def FindInitSegment(self):
        start1 = self.ConnectPortFrom.PortPos()
        start2 = self.ConnectPortTo.PortPos()
        
        if (self.ConnectPortFrom.location=='left'):
            end1 = wxPoint(start1.x-self.PortSegment,start1.y)
        elif (self.ConnectPortFrom.location=='right'):
            end1 = wxPoint(start1.x+self.PortSegment,start1.y)
        elif (self.ConnectPortFrom.location=='top'):
            end1 = wxPoint(start1.x,start1.y-self.PortSegment)
        elif (self.ConnectPortFrom.location=='bottom'):
            end1 = wxPoint(start1.x,start1.y+self.PortSegment)    
            
        if (self.ConnectPortTo.location=='left'):
            end2 = wxPoint(start2.x-self.PortSegment,start2.y)
        elif (self.ConnectPortTo.location=='right'):
            end2 = wxPoint(start2.x+self.PortSegment,start2.y)
        elif (self.ConnectPortTo.location=='top'):
            end2 = wxPoint(start2.x,start2.y-self.PortSegment)
        elif (self.ConnectPortTo.location=='bottom'):
            end2 = wxPoint(start2.x,start2.y+self.PortSegment)

        #if self.ConnectPortFrom.flow =='in': #and self.ConnectPortFrom.PortPos()[0] < self.ConnectPortTo.PortPos()[0] :
        self.PortFromInitSegment = PortConnectionSegment(self.parent,self,wxPoint(end1.x,end1.y),wxPoint(start1.x,start1.y))
        self.PortToInitSegment = PortConnectionSegment(self.parent,self,wxPoint(end2.x,end2.y),wxPoint(start2.x,start2.y))
        if self.ConnectPortFrom.flow =='in':
            self.PortFromInitSegment.AddArrow()
        else:    
            self.PortToInitSegment.AddArrow()
        self.start = end1
        self.end = end2
    def GetContextRect(self):

        #the rectangle with the start and end points of the connection as the topleft and bottomright of the rectangle        
        #print self.start.x,self.end.x
        width=self.end.x-self.start.x
        height=self.end.y-self.start.y
        self.contextrect=wxRect(self.start.x,self.start.y,width,height)
                

    def ExpandContextRectUp(self):
        
        hopcounter=10
        x=self.contextrect.GetLeft()
        y=self.contextrect.GetTop()-hopcounter
        width=self.contextrect.GetWidth()
        height=self.contextrect.GetHeight()+hopcounter
        self.contextrect=wxRect(x,y,width,height)
        #self.GetContextUops(self.uoplist)
        
    def ExpandContextRectDown(self):
        
        hopcounter=10
        x=self.contextrect.GetLeft()
        y=self.contextrect.GetTop()
        width=self.contextrect.GetWidth()
        height=self.contextrect.GetHeight()+hopcounter
        self.contextrect=wxRect(x,y,width,height)
        #self.GetContextUops(self.uoplist)

    def ExpandContextRectLeft(self):
        
        hopcounter=10
        x=self.contextrect.GetLeft()-hopcounter
        y=self.contextrect.GetTop()
        width=self.contextrect.GetWidth()+hopcounter
        height=self.contextrect.GetHeight()
        #self.contextrect=wxRect(x,y,width,height)
        
    def ExpandContextRectRight(self):
        
        hopcounter=10
        x=self.contextrect.GetLeft()
        y=self.contextrect.GetTop()
        width=self.contextrect.GetWidth()+hopcounter
        height=self.contextrect.GetHeight()
        #self.contextrect=wxRect(x,y,width,height)
    def OnDelete(self):
        self.ConnectPortFrom.connection = None
        self.ConnectPortTo.connection = None
        self.ConnectPortFrom.isconnection = False
        self.ConnectPortTo.isconnection = False
        
        for segment in self.PortConnectionSegment:
            can = segment.line.GetCanvas()
            dig = can.GetDiagram()            
            #segment.line.Show(false)
            dig.RemoveShape(segment.line)
            
class PortConnectionSegment:
    def __init__(self,can,PortConnection,FromPos,ToPos):
        self.fromShape = PortConnection.ConnectPortFrom
        self.toShape = PortConnection.ConnectPortTo
        self.line = wxLineShape()
        self.line.Initialise()
        self.line.SetCanvas(can)
        colour = self.fromShape.conn_colour
        pen = wxPen(colour)
        self.line.SetPen(pen)#wxBLACK_PEN)
        self.line.SetBrush(wxBLACK_BRUSH)
        
        self.line.MakeLineControlPoints(2)
        can.diagram.AddShape(self.line)
        
        self.PortConnection = PortConnection
        
        self.SegmentFromPos = FromPos
        self.SegmentToPos = ToPos
    def AddArrow(self):
        self.line.AddArrow(ARROW_ARROW)
        #can.diagram.AddShape(self.line)
        
    def SetPos(self,FromPos,ToPos):
        self.SegmentFromPos = FromPos
        self.SegmentToPos = ToPos
        
    def Draw(self,dc):
        
        #can=self.line.GetCanvas()
        self.line.SetEnds(self.SegmentFromPos.x,self.SegmentFromPos.y,self.SegmentToPos.x,self.SegmentToPos.y)        
        #dc = wxClientDC(can)
        self.line.Show(True)
        #can.PrepareDC(dc)
        self.fromShape.Move(dc, self.fromShape.GetX(), self.fromShape.GetY())
        
    def CheckIfHSegment(self):
        
        if self.SegmentFromPos.y == self.SegmentToPos.y:
            return True
        return False
    
 
class PortEventHandler(wxShapeEvtHandler):
    def __init__(self,parent,cliObj,log):
        wxShapeEvtHandler.__init__(self)
        self.parent = parent
        self.cliObj = cliObj
        self.log = log
            
    def OnLeftClick(self,x,y,key,attach):
        port = self.GetShape()
        if port.isconnection:pass
        else:
            global _isConnectionTakingPlace,_startPort
            if _isConnectionTakingPlace:
                _endPort = port
                
                cmd = _startPort.name + " -> " + _endPort.name
                self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
                self.cliObj.Eval(cmd)
                    
                _isConnectionTakingPlace = false
                _startPort = None
                port.GetCanvas().SetCursor(wxSTANDARD_CURSOR)
            else:
                _isConnectionTakingPlace = true
                _startPort = port
                _endPort = None
                port.GetCanvas().SetCursor(wxCROSS_CURSOR)
            
    def OnRightClick(self,x,y,key,attach):
        print 'port right clicked' 
        shape = self.GetShape()
        pt = wxPoint(x,y)
        #shape.GetCanvas().RightClickForPort(pt,shape)
    
    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
        """print "called"
        shape = self.GetShape()
        shape.SetX(x)
        shape.SetY(y)
        can = shape.GetCanvas()
        dc = wxClientDC(can)
        can.PrepareDC(dc)
        can.Redraw(dc)
        can.Refresh()"""
 
class PaletteEvtHandler(wxShapeEvtHandler):
    def __init__(self):
        wxShapeEvtHandler.__init__(self)

    def OnLeftClick(self,x,y,key,attach):
        shape = self.GetShape()
        shape.GetCanvas().SetCursor(wxCROSS_CURSOR)
        global _isObjectDraggedFromPalette,_currentlyDraggedUnitOp
        _currentlyDraggedUnitOp = shape.GetClass()
        #print _currentlyDraggedUnitOp
        _isObjectDraggedFromPalette = true
 
    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
        """this part of the code is to try if we can move the OGL shapes without selecting them. It works!!
        shape = self.GetShape()
        shape.SetX(x)# + shape.GetWidth()/2)
        shape.SetY(y)# + shape.GetHeight()/2)
        can = shape.GetCanvas()
        dc = wxClientDC(can)
        can.PrepareDC(dc)
        can.Redraw(dc)
        can.Refresh()"""
    
    def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
        donothing = 0

    def OnBeginDragLeft(self,x,y,keys,attach):
        donothing = 1
 
class WorkAreaEvtHandler(wxShapeEvtHandler):
    def __init__(self):
        wxShapeEvtHandler.__init__(self)
        #EVT_RIGHT_UP(self, self.OnRightUp)

    def OnLeftClick(self, x, y, keys = 0, attachment = 0):
        shape = self.GetShape()
        canvas = shape.GetCanvas()
        dc = wxClientDC(canvas)
        canvas.PrepareDC(dc)
        toUnselect = []
        
        if shape.Selected():
            shape.Select(false, dc)
            canvas.Redraw(dc)
        else:
            redraw = false
            shapeList = canvas.GetDiagram().GetShapeList()
            for s in shapeList:
                if s.Selected():
                    toUnselect.append(s)

            if toUnselect:
                for s in toUnselect:
                    s.Select(false, dc)
                canvas.Redraw(dc)    
        shape.Select(true, dc)
        canvas.Refresh()
        global _isObjectDraggedFromPalette
        if _isObjectDraggedFromPalette:
            #canvas.SetCursor(wxCROSS_CURSOR)
            canvas.SetCursor(wxSTANDARD_CURSOR)
            _isObjectDraggedFromPalette = false
            _currentlyDraggedUnitOp = -1
    
    def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
        self.base_OnEndDragLeft(x, y, keys, attachment)
        shape = self.GetShape()
        if not shape.Selected():
            self.OnLeftClick(x, y, keys, attachment)
        shape.GetCanvas().Refresh()
  
    def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
        self.base_OnSizingEndDragLeft(pt, x, y, keys, attch)
        shape = self.GetShape()
        siz = shape.GetBoundingBoxMax()
        shape.size = wxPoint(siz[0],siz[1])
        shape.RelocateUOP()
        
        shape = self.GetShape()
        canvas = shape.GetCanvas()
        dc = wxClientDC(canvas)
        canvas.PrepareDC(dc)
        for portcon in shape.parent.portconnections:
            portcon.Route(shape.parent.listOfUnitOp)
            portcon.Draw(dc)
        shape.GetCanvas().Refresh()

    def OnMovePost(self, dc, x, y, oldX, oldY, display):
        global _portshavebeenmoved
        _portshavebeenmoved = false
        
        shape = self.GetShape()

        if not shape.RelocateUNITOP():
            self.base_OnMovePost(dc, x, y, oldX, oldY, display)
            shape.RelocateUOP()
            #print shape.GetX(),shape.GetY()
            for portcon in shape.parent.portconnections:
                portcon.Route(shape.parent.listOfUnitOp)
                portcon.Draw(dc)
            shape.GetCanvas().Refresh()
    
    def OnRightClick(self,x,y,key,attach):
        pt = wxPoint(x,y)
        shape = self.GetShape()
        canvas = shape.GetCanvas()
        dc = wxClientDC(canvas)
        canvas.PrepareDC(dc)
        toUnselect = []
        
        if shape.Selected():
            shape.Select(false, dc)
            canvas.Redraw(dc)
        else:
            redraw = false
            shapeList = canvas.GetDiagram().GetShapeList()
            for s in shapeList:
                if s.Selected():
                    toUnselect.append(s)
            if toUnselect:
                for s in toUnselect:
                    s.Select(false, dc)
                canvas.Redraw(dc)
        canvas.Refresh()
        shape.Select(true, dc)
        global _isObjectDraggedFromPalette,_currentlyDraggedUnitOp
        if _isObjectDraggedFromPalette:
            canvas.SetCursor(wxSTANDARD_CURSOR)
            _currentlyDraggedUnitOp = -1
            _isObjectDraggedFromPalette = false

        shape.GetCanvas().RightClickForUnitop(pt,shape)
    
class UnitOpTreeCtrl(wxTreeCtrl):
    """Unit Operations Tree"""
    def __init__(self, parent, id, pos, size, style):
        wxTreeCtrl.__init__(self, parent, id, pos, size, style)
        

    def OnCompareItems(self, item1, item2):
        #pass
        t1 = self.GetItemText(item1)
        t2 = self.GetItemText(item2)
        
        if t1 < t2: return -1
        if t1 == t2: return 0
        return 1

class UopTreeControlName:
    def __init__(self,name):
        self.name=name
        self.count=1
   
class UnitOpTreeCtrlPanel(wxPanel):
    """"Unit aOperation Tree Panel"""
    def __init__(self,parent,log):
        # Use the WANTS_CHARS style so the panel doesn't eat the Return key.
        
        wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS)
        EVT_SIZE(self, self.OnSize)
        self.ListOfUopTypes = []
        self.log = log
        tID =wxNewId()

        self.tree = UnitOpTreeCtrl(self, tID, wxDefaultPosition, wxDefaultSize,
                               wxTR_HAS_BUTTONS
                               | wxTR_EDIT_LABELS
                               )

        self.itemlist=[]
        self.root = self.tree.AddRoot("Unit Operations")
        self.ListOfUopTypes = []
        global listOfParsedUnitOpFiles
        for type in listOfParsedUnitOpFiles.keys():
            child = self.tree.AppendItem(self.root, type)
            self.ListOfUopTypes.append(child)
            self.tree.SetPyData(child, None)

        self.tree.Expand(self.root)
        EVT_TREE_ITEM_EXPANDED  (self, tID, self.OnItemExpanded)
        EVT_TREE_ITEM_COLLAPSED (self, tID, self.OnItemCollapsed)
        EVT_TREE_SEL_CHANGED    (self, tID, self.OnSelChanged)
        EVT_TREE_ITEM_ACTIVATED (self, tID, self.OnActivate)

        EVT_LEFT_DCLICK(self.tree, self.OnLeftDClick)

    def append(self,_name,_class):
        cookie = 1
        child = self.tree.GetFirstChild(self.root,cookie)
        text = self.tree.GetItemText(child[0])
        
        if text==_class:
            self.tree.AppendItem(child[0], _name)
            #self.ListOfUopTypes.append(child[0])
            self.tree.SetPyData(child[0], None)
            self.tree.Expand(child[0])
        else:
            found = false
            while( not found):
                child = self.tree.GetNextChild(self.root,child[1])
                text = self.tree.GetItemText(child[0])
                #text = wxString(text)
                if text==_class:
                    self.tree.AppendItem(child[0], _name)
                    #self.ListOfUopTypes.append(child[0])
                    self.tree.SetPyData(child[0], None)
                    self.tree.Expand(child[0])
                    found= true
                    
    def deleteItem(self,_name):
        
        cookie = 1
        _name = _name[1:]
        for uoptype in self.ListOfUopTypes:
            
            cookie=1
            child = self.tree.GetFirstChild(uoptype,cookie)
            text = self.tree.GetItemText(child[0])
            
            if text==_name:
                self.tree.Delete(child[0])
                self.tree.Expand(self.root)
                return
            else:
                found = false
                while(not found):
                    child = self.tree.GetNextChild(uoptype,child[1])
                    text = self.tree.GetItemText(child[0])
                    if text=="":
                        found = true
                    if text==_name:
                        self.tree.Delete(child[0])
                        self.tree.Expand(self.root)
                        found= true   
                    
    def OnLeftDClick(self, event):
        pt = event.GetPosition();
        item, flags = self.tree.HitTest(pt)
        parent = self.tree.GetItemParent(item)
        #self.tree.SortChildren(parent)

    def OnSize(self, event):
        w,h = self.GetClientSizeTuple()
        self.tree.SetDimensions(0, 0, w, h)

    def OnItemExpanded(self, event):
        item = event.GetItem()
        
    def OnItemCollapsed(self, event):
        item = event.GetItem()
        
        
    def OnSelChanged(self, event):
        self.item = event.GetItem()
        items = self.tree.GetSelections()
        #print map(self.tree.GetItemText, items)
        event.Skip()


    def OnActivate(self, evt):
        pass

    def Message(self,message,args):
        #self.log.WriteText('Sim42PFD.PyInfoMessage: ' + str(message) + ',' +  str(args) + "\n")
        if message == 'CMDNotifyCreateObj':
            _name = args[0] + args[1]
            _class = args[2]
            temp = string.split(_class,"(")
            _class = temp[0]
            self.Refresh(True)
            self.append(_name,_class)
        elif message == 'CMDNotifyDeleteObj':
            _name = args[0] + args[1]
            self.Refresh(True)
            
            self.deleteItem(_name)  
        
class MyPrintout(wxPrintout):
    def __init__(self, canvas):
        wxPrintout.__init__(self)
        self.canvas = canvas
        

    def OnBeginDocument(self, start, end):
        #self.log.WriteText("wxPrintout.OnBeginDocument\n")
        return self.base_OnBeginDocument(start, end)

    def OnEndDocument(self):
        #self.log.WriteText("wxPrintout.OnEndDocument\n")
        self.base_OnEndDocument()

    def OnBeginPrinting(self):
        #self.log.WriteText("wxPrintout.OnBeginPrinting\n")
        self.base_OnBeginPrinting()

    def OnEndPrinting(self):
        #self.log.WriteText("wxPrintout.OnEndPrinting\n")
        self.base_OnEndPrinting()

    def OnPreparePrinting(self):
        #self.log.WriteText("wxPrintout.OnPreparePrinting\n")
        self.base_OnPreparePrinting()

    def HasPage(self, page):
        #self.log.WriteText("wxPrintout.HasPage: %d\n" % page)
        if page <= 2:
            return True
        else:
            return False

    def GetPageInfo(self):
        #self.log.WriteText("wxPrintout.GetPageInfo\n")
        return (1, 2, 1, 2)

    def OnPrintPage(self, page):
        #self.log.WriteText("wxPrintout.OnPrintPage: %d\n" % page)
        dc = self.GetDC()

        #-------------------------------------------
        # One possible method of setting scaling factors...

        maxX = self.canvas.getWidth()
        maxY = self.canvas.getHeight()

        # Let's have at least 50 device units margin
        marginX = 50
        marginY = 50

        # Add the margin to the graphic size
        maxX = maxX + (2 * marginX)
        maxY = maxY + (2 * marginY)

        # Get the size of the DC in pixels
        (w, h) = dc.GetSizeTuple()

        # Calculate a suitable scaling factor
        scaleX = float(w) / maxX
        scaleY = float(h) / maxY

        # Use x or y scaling factor, whichever fits on the DC
        actualScale = min(scaleX, scaleY)

        '''# Calculate the position on the DC for centring the graphic
        posX = (w - (self.canvas.getWidth() * actualScale)) / 2.0
        posY = (h - (self.canvas.getHeight() * actualScale)) / 2.0'''

        posX = 0
        posY = 0
        # Set the scale and origin

        dc.SetUserScale(actualScale, actualScale)
        dc.SetDeviceOrigin(int(posX), int(posY))

        #-------------------------------------------

        self.canvas.Redraw(dc)
        dc.DrawText("Page: %d" % page, marginX/2, maxY-marginY)

        return True


class TestPrintPanel(wxPanel):
    def __init__(self, parent, frame,canvas):
        wxPanel.__init__(self, parent, -1)
        self.frame = frame
        self.canvas = canvas

        self.printData = wxPrintData()
        self.printData.SetPaperId(wxPAPER_LETTER)

        self.box = wxBoxSizer(wxHORIZONTAL)
        btn = wxButton(self, 1201, "Print Setup")
        EVT_BUTTON(self, 1201, self.OnPrintSetup)
        self.box.Add(btn, 1, wxGROW | wxALL, 2)

        btn = wxButton(self, 1202, "Print Preview")
        EVT_BUTTON(self, 1202, self.OnPrintPreview)
        self.box.Add(btn, 1, wxGROW | wxALL, 2)

        btn = wxButton(self, 1203, "Print")
        EVT_BUTTON(self, 1203, self.OnDoPrint)
        self.box.Add(btn, 1, wxGROW | wxALL, 2)

        self.SetAutoLayout(True)
        self.SetSizer(self.box)


    def OnPrintSetup(self, event):
        printerDialog = wxPrintDialog(self)
        printerDialog.GetPrintDialogData().SetPrintData(self.printData)
        printerDialog.GetPrintDialogData().SetSetupDialog(True)
        printerDialog.ShowModal();
        self.printData = printerDialog.GetPrintDialogData().GetPrintData()
        printerDialog.Destroy()


    def OnPrintPreview(self, event):
        #self.log.WriteText("OnPrintPreview\n")
        printout = MyPrintout(self.canvas)
        printout2 = MyPrintout(self.canvas)
        self.preview = wxPrintPreview(printout, printout2, self.printData)
        if not self.preview.Ok():
            #self.log.WriteText("Houston, we have a problem...\n")
            return

        frame = wxPreviewFrame(self.preview, self.frame, "This is a print preview")

        frame.Initialize()
        frame.SetPosition(self.frame.GetPosition())
        frame.SetSize(self.frame.GetSize())
        frame.Show(True)



    def OnDoPrint(self, event):
        pdd = wxPrintDialogData()
        pdd.SetPrintData(self.printData)
        printer = wxPrinter(pdd)
        printout = MyPrintout(self.canvas)
        if not printer.Print(self.frame, printout):
            wxMessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wxOK)
        else:
            self.printData = printer.GetPrintDialogData().GetPrintData()
        printout.Destroy()
        
class PfdFrame(wxFrame):
    def __init__(self,parent,CliObj):
        wxFrame.__init__(self, parent, -1, "Vector diagrams", pos = (0,0), size=(1024,720),
                         style = wxMAXIMIZE | wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
        self.CliObj = CliObj
        initialize()
        buildPorts()
        buildUnitOps()

        splitter0 = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
        splitter1 = wxSplitterWindow(splitter0, -1, style=wxNO_3D|wxSP_3D)
        splitter2 = wxSplitterWindow(splitter1, -1, style=wxNO_3D|wxSP_3D)
        splitter3 = wxSplitterWindow(splitter1,-1, style=wxNO_3D|wxSP_3D)
        
        self.log = wxTextCtrl(splitter3, -1,style = wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL)
        #wxLog_SetActiveTarget(MyLog(self.log))
        
        self.a = Palette(splitter2,self.CliObj,self.log)
        #self.b = grid.UnitOpPropertyGrid(splitter3,-1)
        self.c = WorkArea(splitter3,self.CliObj,self.log)
        self.d = UnitOpTreeCtrlPanel(splitter2,self.log)
        self.e = TestPrintPanel(splitter0,self,self.c)
        

       
        splitter0.SplitHorizontally(self.e, splitter1, 30)
        splitter1.SplitVertically(splitter2,splitter3, 230)
        splitter2.SplitHorizontally(self.a, self.d, 500)
        splitter3.SplitHorizontally(self.c, self.log, 500)
        
        splitter0.SetMinimumPaneSize(20)
        splitter1.SetMinimumPaneSize(20)
        splitter2.SetMinimumPaneSize(20)
        splitter3.SetMinimumPaneSize(20)

        '''
        splitter = wxSplitterWindow(self, -1, style=wxNO_3D|wxSP_3D)
        self.pal = Palette(splitter,self.CliObj)
        self.workArea = WorkArea(splitter,self.CliObj)
        splitter.SplitVertically(self.pal,self.workArea,210)        '''
        self.Show(true)

    def dele(self):
        self.a.destroy(true)
        
    def Message(self,message,args):
        self.log.WriteText('Sim42PFD.PyInfoMessage: ' + str(message) + ',' +  str(args) + "\n")
        self.c.Message(message,args)
        self.d.Message(message,args)

class PFD:
    def __init__(self,CliObj):
        self.CliObj = CliObj
        self.frame = None
    def make(self):
        self.app = wxPySimpleApp()
        self.frame=PfdFrame(None,self.CliObj)
        #self.frame=PfdFrame(None)
        self.log = self.frame.log
        cmd = 'units VMG'
        self.log.WriteText("Sim42PFD.TestEval: " + cmd + "\n")
        self.CliObj.Eval(cmd)
        cmd = '/LiquidPhases = 2'
        self.log.WriteText("Sim42PFD.TestEval: " + cmd+ "\n")
        self.CliObj.Eval(cmd)
        cmd = '/RecycleDetails = 1'
        self.log.WriteText("Sim42PFD.TestEval: " + cmd+ "\n")
        self.CliObj.Eval(cmd)
                
    def makee(self):
        self.frame.Show(true)
        self.app.MainLoop()
        
    def Message(self,message,args):
        self.frame.Message(message,args)
